package kr.co.bettersoft.sendme.activity;

import java.io.File;
import java.util.ArrayList;

import kr.co.bettersoft.sendme.provider.SendMeBlock;
import kr.co.bettersoft.sendme.provider.SendMeFile;
import kr.co.bettersoft.sendme.provider.SendMeFriend;
import kr.co.bettersoft.sendme.provider.SendMeLog;
import kr.co.bettersoft.sendme.provider.SendMeReceiveMessageForPlayerSlideMenuAdapter;
import kr.co.bettersoft.sendme.provider.SendMeRecognition;
import kr.co.bettersoft.sendme.provider.SendMeVoice;
import kr.co.bettersoft.sendme.rest.SendMeAudioMessageRest;
import kr.co.bettersoft.sendme.rest.SendMeBlockRest;
import kr.co.bettersoft.sendme.rest.SendMeLogRest;
import kr.co.bettersoft.sendme.rest.SendMeRecognitionRest;
import kr.co.bettersoft.sendme.util.SendMeActivityManager;
import kr.co.bettersoft.sendme.util.SendMeCommon;
import kr.co.bettersoft.sendme.util.SendMeConstant;
import kr.co.bettersoft.sendme.util.SendMeDBManagerAudioRecord;
import kr.co.bettersoft.sendme.util.SendMeDBManagerInstallUser;
import kr.co.bettersoft.sendme.util.SendMeSlideMyHorizontalScrollView;
import kr.co.bettersoft.sendme.util.SendMeSlideSizeCallbackForMenu;
import kr.co.bettersoft.sendme.activity.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

/**
 * 임시 보관 메시지를 재생할때 사용되는 액티비티 클래스이다.
 *  녹음 화면에서 녹음 이후 재생할때 처럼 기본적인 재생 기능이 있고
 *  하단 버튼들은 녹음화면에서의 기능과 다르므로 새롭게 구현되어 있다.
 *  
 *  하단 버튼 목록
 *   재생 : 음성 메시지 재생			: 파일 절대 경로 필요 filePath
 *   전송 : 음성 메시지 전송  (성공시 이후 삭제 처리)		: sender, receiver, fileName,  
 *   예약 : 음성 메시지 예약 전송  (성공시 이후 삭제 처리)  : sender, receiver, fileName, 
 *   삭제 : 음성 메시지 삭제 (sqlite 에서도 삭제하고, 로컬 파일도 함께 삭제). 삭제 후 화면을 닫고 임시 보관함으로 이동..	: id, filePath, 
 * @author blue
 *
 */
public class SendMeAudioPlayForReceiveMessageActivity extends Activity implements OnClickListener, OnCompletionListener{

	public static String TAG = SendMeAudioPlayForReceiveMessageActivity.class.getSimpleName();
	
	// 액티비티 매니저를 가져 온다.
	private SendMeActivityManager sendMeActivityManager = SendMeActivityManager.getInstance();

	String applicationAudioTempDirectory = SendMeConstant.APPLICATION_AUDIO_TEMP_DIRECTORY; 		//"/Android/data/kr.pe.jonhkim.sendme.activity/.AudioRecord/temp";			// 녹음 중인 임시파일 저장될 경로 지정, 탐색기,미디어 스캐너에 나타나지 않게 비공개 처리 

	// 녹음 음성 재생기
	private MediaPlayer mPlayer = null;

	// 파일명
	String fileName;

	// 파일명 포함하는 파일 경로			// 다운 받은 파일이 임시 저장될 경로. 다운받을때 새로 생성해주어야 하며 따로 저장해 두어야 함. 
	String filePath;
	
	// 보내는 사람 전번		
	String sender;
	
	// 접속 모드 PUBLIC /MASTER
	String FUNCTION_MODE = "";
	
	// 전달받은 키 값
	String receiveIdSendMeVoice;
	// 전달 받은 받는 사람 전번 등 정보
	String receiveSender ;
	String receiveSenderName;		// 이름(실제 값은 닉네임)
	String receiveFileName;		
	String receiveIdSendMeFile;		
	String[] receiverList ;
	String[] receiverNameList ;
	// 읽음 여부. 읽지 않은 경우에만 업데이트 하기 위함.
	String receiveReadYn;
//	
//	String sqliteKey;
//	String receiver;
//	String receiverName;
	
	// 보낸 사람 표시 뷰
	TextView audioRecordSenderNameTxt;

	// 녹음 시간
	private int mProgressCheckStepMs = SendMeConstant.mProgressCheckStepMs;		// 녹음 및 재생에서 진행바의 갱신 간격(ms 단위) : 0.5초마다 체크
	
	// 재생 중 표시
	SeekBar playSeekbar;		// 재생 진행 상태 바
	TextView mTvPlayMaxPoint;	// 전체 재생 시간

	// 하단 녹음 이후 메뉴 버튼들
	ImageButton menuPlayBtn;	// 1
	ImageButton menuReplyBtn;	// 2
	ImageButton menuSaveBtn;	// 3
	ImageButton menuBlockBtn;	// 4
	ImageButton menuDeleteBtn;	// 5

	// 상단 재생 관련 스크린 레이아웃
	View audioPlayScreenLayout;
	// 하단 녹음 이후 메뉴 레이아웃
	View bottomRecordMenuLayout;

	ImageButton imageButtonTopBack;
	ImageButton imageButtonTopMainMenu;
	
	// 프로그래스바(로딩 표시)
	private ProgressDialog dialog;
	
	
	
	// 좌측 슬라이드 리스트
	ListView listViewReceiveMessage;
	// 음성 메시지 어댑터 클래스.
	private SendMeReceiveMessageForPlayerSlideMenuAdapter sendMeReceiveMessageForPlayerSlideMenuAdapter;		
	// 메시지 목록
	private ArrayList<SendMeVoice> receiveMessageList = null;		
	// 리스트에서 클릭한 버튼이 위치한 포지션
	SendMeVoice selectedItem;
	
	
	
	
	
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	// slide 처리.  (여러가지 소스를 섞어서 구현됨)
	
	// 1. 페이스북 스타일의 화면 덮기 관련
	private DisplayMetrics metrics;	// 왼쪽 영역이 화면에 나타날 크기를 설정하는 용도.  화면의 3/4 정도가 적당함
	int scrollingWidthBandwith;		// 메뉴 부르기 위해 밀어야 되는 화면의 최소 거리. 일정 거리 이상 밀어줘야 나타남
	boolean isLeftExpanded;			// 확장되었는지 여부(왼쪽이 열렸는지)

	// 2. 액티비티 슬라이드 이벤트 받아서 처리하기 (화면을 밀어서 불러오기 관련)
	/** ViewFlipper 컴포넌트 객체 */  
	private ViewFlipper m_viewFlipper;  			// 이 영역을 밀어서 호출함
	/** ViewFilpper 안에서 터치된 X축의 좌표 */  
	private int m_nPreTouchPosX = 0;
	
	// 3. 우측 메인 화면이 압축되지 않고 그대로 밀려나도록 하기 위하여 필요
	SendMeSlideMyHorizontalScrollView scrollView;
	View menu;
	View app;
		
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 로그를 남긴다
	private static final int THREAD_REGISTER_LOG = 100;
	
	// 서버에서 받은 메시지 목록을 조회한다
	private static final int THREAD_SELECT_RECEIVE_MESSAGE_LIST = 102;		

	// 조회한 리스트를 화면에 세팅한다
	private static final int THREAD_SHOW_RECEIVE_MESSAGE_LIST = 103;
	
	// 받은 메시지 파일을 서버로부터 받는다.
	private static final int THREAD_DOWNLOAD_AUDIO_FILE = 104;
	
	// 녹음 재생 준비
	private static final int THREAD_INIT_PLAYING = 115;
	
	// 녹음을 재생한다
	private static final int THREAD_PLAYING_RECORD = 105;
	
	// 프로그레스 바를 출력 한다.
	private static final int THREAD_PROGRESS_BAR_VISIBLE = 108;

	// 프로그레스 바를 감춘다.
	private static final int THREAD_PROGRESS_BAR_INVISIBLE = 109;

	// 등록 성공 토스트를 띄운다
	private static final int THREAD_TOAST_SEND_SUCCESS = 110;

	// 등록 실패 토스트를 띄운다
	private static final int THREAD_TOAST_SEND_FAIL = 112;		

	// 받은 음성 메시지를 저장함에 저장할지 확인받는다
	private static final int CONFIRM_SAVE_RECEIVE_AUDIO_FILE = 121;		
	
	// 받은 음성 메시지를 저장함에 저장한다
	private static final int THREAD_SAVE_RECEIVE_AUDIO_FILE = 122;		
	
	// 저장 성공 토스트를 띄운다
	private static final int THREAD_TOAST_SAVE_SUCCESS = 131;			
	
	// 저장 실패 토스트를 띄운다
	private static final int THREAD_TOAST_SAVE_FAIL = 132;		
	
	// 받은 저장 음성 메시지를 서버에서 삭제할지 확인받는다
	private static final int CONFIRM_DELETE_RECEIVE_AUDIO_FILE = 123;		
	
	// 받은 저장 음성 메시지를 서버에서 삭제 한다
	private static final int THREAD_DELETE_RECEIVE_AUDIO_FILE = 124;		
	// 받은 저장 음성 메시지를 서버에서 삭제 하고 종료한다
	private static final int THREAD_DELETE_RECEIVE_AUDIO_FILE_AND_FINISH = 125;	
	
	// 삭제 성공 토스트를 띄운다
	private static final int THREAD_TOAST_DELETE_SUCCESS = 116;	
	
	// 삭제 실패 토스트를 띄운다
	private static final int THREAD_TOAST_DELETE_FAIL = 118;		
	
	// 사용자 확인 창을 띄운다
	private static final int ALERT_SHOW_MESSAGE = 136;
	
	// 사용자를 차단할지 확인 받는다
	private static final int THREAD_CONFIRM_BLOCK_USER = 147;
	// 사용자를 차단한다
	private static final int THREAD_BLOCK_USER = 148;
	
	// 토스트 - 이미 차단하였습니다.		
	private static final int THREAD_TOAST_ALREADY_BLOCK = 151;
	// 토스트 - 차단하였습니다.
	private static final int THREAD_TOAST_BLOCK_SUCCESS = 152;
	// 토스트 - 차단 요청이 실패하였습니다.
	private static final int THREAD_TOAST_BLOCK_FAIL = 153;
	
	// 메시지 읽음 업데이트
	private static final int THREAD_UPDATE_READ_YN = 161;
	
	// 녹음 화면 호출
	private static final int RECORDING_SCREEN_CALL = 135;
	
	// 예약 화면에서 메뉴를 콜함. 이 액티비티도 종료해야함
	private static final int RESULT_MAIN_MENU_CALLED = 600;			
	
	// 암호 설정 액티비티 요청 코드
	private static final int PASSWORD_ACTIVITY_CODE = 134;	
	private static final int ACTION_CODE_MASTER_KEY_CHECK  = 212;		//  마스터 키 확인
	private static final int ACTION_CODE_PUBLIC_KEY_CHECK  = 222;		//  퍼블릭 키 확인
	
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	// 재생시 SeekBar 처리
	Handler mProgressHandler2 = new Handler()
	{
		public void handleMessage(Message msg)
		{
			if (mPlayer == null) return;
			try
			{
				if (mPlayer.isPlaying())
				{
					if(mPlayer.getCurrentPosition()>0){		// 재생 끝나고나서도 동작되어 0이 표시되는 경우가 있기 때문에 0은 표시해주지 않도록 처리
						playSeekbar.setProgress(mPlayer.getCurrentPosition());
					}
					mProgressHandler2.sendEmptyMessageDelayed(0, mProgressCheckStepMs);
				}
			}
			catch (IllegalStateException e)
			{}
			catch (Exception e)
			{}
		}
	};

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// 커스텀 타이블 바를 설정 한다.
		Window window = getWindow();
		window.requestFeature(Window.FEATURE_CUSTOM_TITLE);
		
		// 슬라이드 메뉴 작업
		LayoutInflater inflater = LayoutInflater.from(this);
		scrollView = (SendMeSlideMyHorizontalScrollView) inflater.inflate(R.layout.slide_my_horizontal_scroll_view, null);
		setContentView(scrollView);
		window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_bar_03);
		
		
		// 뒤로 가기 화살표 버튼을 설정 한다.
		imageButtonTopBack = (ImageButton)findViewById(R.id.imageButtonTopBack);
		imageButtonTopBack.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub

				Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
				startActivity(intent);
				
				// 화면을 닫는다.
				deleteFileAndFinishActivity();
			}
		});

		// 타이틀바의 메인 메뉴 버튼을 설정 한다.
		imageButtonTopMainMenu = (ImageButton)findViewById(R.id.imageButtonTopMainMenu);
		imageButtonTopMainMenu.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Log.i(TAG, "pressed top main menu.");

				// 메인 메뉴 화면을 출력 한다.
				Intent i = new Intent(SendMeAudioPlayForReceiveMessageActivity.this, SendMeMainMenuActivity.class);
				startActivity(i);
				
				// 화면을 닫는다.
				deleteFileAndFinishActivity();
			}
		});
		
		
		
		
		// 메인으로 쓸거 app 과 슬라이드 메뉴로 쓸거 menu 를 지정한다 (xml파일)
		menu = inflater.inflate(R.layout.activity_send_me_play_for_receive_message_left_slide_menu, null);
		app = inflater.inflate(R.layout.activity_send_me_play_for_receive_message, null);
		
		
		// 좌측 슬라이드 기능 초기화.
		initSlideFunction();
		
		// 액티비티 매니저에 담는다.
		sendMeActivityManager.addActivity(this);

		// 내 전화번호 (보낸 사람 전화번호) 획득
		confirmNotification();

		// 전달받은 받는 사람(리스트) 를 획득						
		Intent receiveIntent = getIntent();
		
		receiveIdSendMeVoice = receiveIntent.getStringExtra("idSendMeVoice");
		receiveSender = receiveIntent.getStringExtra("sender");
		receiveSenderName = receiveIntent.getStringExtra("senderName");
		receiveFileName = receiveIntent.getStringExtra("fileName");
		receiveIdSendMeFile = receiveIntent.getStringExtra("idSendMeFile");
		receiveReadYn = receiveIntent.getStringExtra("readYn");		
		Log.d(TAG,"receiveReadYn:"+receiveReadYn);
		// 답장을 보낼땐 전달받은 보낸 사람 전화번호가 받을 사람 전화번호가 된다.
		SendMeCommon sendMeCommon = new SendMeCommon();
		receiverList = sendMeCommon.convertStringToArray(receiveSender);
		receiverNameList = sendMeCommon.convertStringToArray(receiveSenderName);
		
		
		// 좌측 슬라이드 메뉴 - 메시지 리스트 . = 좌측에 있는 것을 사용하므로 menu. 으로 지정
		listViewReceiveMessage = (ListView) menu.findViewById(R.id.listViewReceiveMessage);
		sendMeReceiveMessageForPlayerSlideMenuAdapter = new SendMeReceiveMessageForPlayerSlideMenuAdapter(getApplicationContext(), this, receiveMessageList);
		
		
			
		
		// 상단 재생 관련 스크린 레이아웃
		audioPlayScreenLayout = (View) app.findViewById(R.id.audio_play_screen_layout);					// 녹음 후
		// 하단 버튼 레이아웃들
		bottomRecordMenuLayout = (View) app.findViewById(R.id.audio_record_bottom_menu_layout);					// 녹음 후

		/*
		 * 재생 진행바
		 */
		mTvPlayMaxPoint = (TextView) app.findViewById(R.id.tvPlayMaxPoint);		// 시간 표시
		playSeekbar = (SeekBar) app.findViewById(R.id.play_seekbar);
		playSeekbar.setOnTouchListener(new OnTouchListener() {public boolean onTouch(View v, MotionEvent event) {
			playSeekbarChange(v);
			return false; }
		});

		// 메뉴 버튼들
		menuPlayBtn = (ImageButton) app.findViewById(R.id.menu_play_btn);
		menuPlayBtn.setOnClickListener(this);
		
		menuReplyBtn = (ImageButton) app.findViewById(R.id.menu_reply_btn);
		menuReplyBtn.setOnClickListener(this);
		
		menuSaveBtn = (ImageButton) app.findViewById(R.id.menu_save_btn);		 
		menuSaveBtn.setOnClickListener(this);

		menuBlockBtn = (ImageButton) app.findViewById(R.id.menu_block_btn);
		menuBlockBtn.setOnClickListener(this);

		menuDeleteBtn = (ImageButton) app.findViewById(R.id.menu_delete_btn);	 
		menuDeleteBtn.setOnClickListener(this);

		// 보낸 사람 이름 표시 뷰(재생용)
		audioRecordSenderNameTxt = (TextView) app.findViewById(R.id.audioRecordSenderNameTxt);
		
		// 이름 있으면 이름으로 표시, 없으면 전번으로 표시
		if(receiveSenderName!=null && receiveSenderName.length()>0){
				audioRecordSenderNameTxt.setText(receiveSenderName);	// receiverList --> receiverNameList
		}else{
			audioRecordSenderNameTxt.setText(receiveSender);
		}
		
		// 로깅.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_REGISTER_LOG));
		
		// 보안 설정시. 마스터 키를 입력 받고 나서 진행
		if(FUNCTION_MODE.equals("MASTER")){
			// 마스터키를 입력 받는다.
			Intent passwordActivity = new Intent(SendMeAudioPlayForReceiveMessageActivity.this, SendMePasswordActivity.class);
			passwordActivity.putExtra("ACTION_CODE", ACTION_CODE_MASTER_KEY_CHECK);
			startActivityForResult(passwordActivity, PASSWORD_ACTIVITY_CODE);
		
		}else if(FUNCTION_MODE.equals("PUBLIC")){
			// 퍼블릭키를 입력 받는다.
			Intent passwordActivity = new Intent(SendMeAudioPlayForReceiveMessageActivity.this, SendMePasswordActivity.class);
			passwordActivity.putExtra("ACTION_CODE", ACTION_CODE_PUBLIC_KEY_CHECK);
			startActivityForResult(passwordActivity, PASSWORD_ACTIVITY_CODE);
			
		// 비밀번호 설정이 되어있지 않으면 그냥 사용.	
		}else{
			// 메시지 읽음 업데이트
			if(!receiveReadYn.equals("Y")){
				Log.d(TAG," ### 1");
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_UPDATE_READ_YN));		
			}
			
			// 음성 메시지 파일 다운로드 --> 끝나고 리스트 받아와서 세팅
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_DOWNLOAD_AUDIO_FILE));
		}
		
	}

	/*
	 * 하단 메뉴 버튼 클릭 리스너
	 */
	@Override
	public void onClick(View v) {
		switch (v.getId()) {

			// 재생
		case R.id.menu_play_btn:
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_PLAYING_RECORD));
			break;
			
			// 답장
		case R.id.menu_reply_btn:
			recordForReply();
			break;
			
			// 저장
		case R.id.menu_save_btn:
			// 이미 로컬에는 있으니까 sqlite 에 저장만 하면 됨. 확인 받기. 
			mHandler.sendMessage(mHandler.obtainMessage(CONFIRM_SAVE_RECEIVE_AUDIO_FILE));
			break;
			
			// 차단
		case R.id.menu_block_btn:
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_CONFIRM_BLOCK_USER));		
			break;
			
			// 삭제
		case R.id.menu_delete_btn:
			// 삭제 확인, 삭제 후 닫기
			mHandler.sendMessage(mHandler.obtainMessage(CONFIRM_DELETE_RECEIVE_AUDIO_FILE));
			break;
		}
	}

	// 답장
	public void recordForReply(){
		Log.d(TAG,"recordForReply");
		Intent intent = new Intent(SendMeAudioPlayForReceiveMessageActivity.this, SendMeAudioRecordActivity.class);
		intent.putExtra("receiverList", receiverList);
		intent.putExtra("receiverNameList", receiverNameList);
		startActivityForResult(intent, RECORDING_SCREEN_CALL);		
	}	
	
	
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 확인창.
	/**
	 * 음성 메시지 삭제 전 확인 창을 띄운다
	 * 
	 */
	private Runnable confirmDeleteAudioToDownload = new Runnable() {
		@Override
		public void run() {
			
			new AlertDialog.Builder(SendMeAudioPlayForReceiveMessageActivity.this)
			.setTitle("삭제 확인")
			.setMessage("음성 메시지를 삭제하시겠습니까?")
			.setNegativeButton("취소", new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {

				}
			})
			.setPositiveButton("확인", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_DELETE_RECEIVE_AUDIO_FILE));
				}
			}).show();
			
		}
	};
	/**
	 * 음성 메시지 저장함에 저장할지 확인 창을 띄운다			
	 * 
	 */
	private Runnable confirmSaveAudioToStorage = new Runnable() {
		@Override
		public void run() {
			
			new AlertDialog.Builder(SendMeAudioPlayForReceiveMessageActivity.this)
			.setTitle("보관 확인")
			.setMessage("음성 메시지를 보관하시겠습니까?")
			.setNegativeButton("취소", new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {

				}
			})
			.setPositiveButton("확인", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_SAVE_RECEIVE_AUDIO_FILE));
				}
				
			}).show();
			
		}
	};
	
	/**
	 * 차단 전 확인 창을 띄운다
	 * 
	 */
	private Runnable confirmBlockUser = new Runnable() {		
		@Override
		public void run() {

			new AlertDialog.Builder(SendMeAudioPlayForReceiveMessageActivity.this)
			.setTitle("차단 확인")
			.setMessage("해당 사용자를 차단하시겠습니까?")
			.setNegativeButton("취소", new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {

				}
			})
			.setPositiveButton("확인", new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_BLOCK_USER));
				}
			}).show();

		}
	};
	
	
	
	// 토스트
	/**
	 * 음성 메시지 전송에 성공했다는 toast 를 띄운다.
	 */
	public void showToastAudioSendSuccess() {					
		CharSequence text = "메시지가 전송 되었습니다";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	/**
	 * 음성 메시지 전송에 실패했다는 toast 를 띄운다.
	 */
	public void showToastAudioSendFail() {
		CharSequence text = "메시지 전송에 실패하였습니다";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	
	/**
	 *  음성 메시지 삭제에 성공했다는 toast 를 띄운다.		
	 */
	public void showToastAudioDeleteToSuccess() {
		CharSequence text = "삭제되었습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
		
		
//		// 화면을 닫는다.
//		sendMeActivityManager.removeActivity(SendMeAudioPlayForReceiveMessageActivity.this);
//		finish();
		mediaPlayerReleaseAndFinishThisActivity();
	}
	/**
	 * 음성 메시지 삭제에 실패했다는 toast 를 띄운다.
	 */
	public void showToastAudioDeleteToFail() {
		CharSequence text = "삭제에 실패하였습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	
	/**
	 * 음성 메시지를 보관함에 저장 성공했다는 toast 를 띄운다	
	 */
	public void showToastAudioSaveToDownloadSuccess() {
		CharSequence text = "보관함에 저장되었습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
		
//		// 화면을 닫는다.
//		sendMeActivityManager.removeActivity(SendMeAudioPlayForReceiveMessageActivity.this);
//		finish();
		mediaPlayerReleaseAndFinishThisActivity();
	}
	/**
	 *  음성 메시지를 보관함에 저장 실패했다는 toast 를 띄운다.
	 */
	public void showToastAudioSaveToDownloadFail() {
		CharSequence text = "저장 실패했습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	
	/**
	 * 이미 차단된 사용자 toast 를 띄운다.
	 */
	public void showToastAlreadyBlockUser() {					
		CharSequence text = "이미 차단된 사용자입니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	/**
	 * 사용자를 차단했다는 toast 를 띄운다.
	 */
	public void showToastBlockUserSuccess() {					
		CharSequence text = "해당 사용자를 차단하였습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	/**
	 * 차단 요청이 실패했다는 toast 를 띄운다.
	 */
	public void showToastBlockUserFail() {					
		CharSequence text = "차단 요청이 실패하였습니다.";
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  

	/**
	 * 필요한 핸들러를 등록해서 사용한다.
	 */
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			Bundle b = msg.getData();
			
			switch(msg.what) {
			
			// 로그를 남긴다
			case THREAD_REGISTER_LOG : 
				threadRegisterLog();
				break;
				
				// 메시지 목록을 세팅
			case THREAD_SELECT_RECEIVE_MESSAGE_LIST : 
				threadSelectVoiceList();
				break;
				// 메시지 목록을 출력 한다.		
			case THREAD_SHOW_RECEIVE_MESSAGE_LIST : 
				runOnUiThread(showReceiveMessageList);
				break;
				
			// 서버에서 음성 메시지 파일을 다운받는다
			case THREAD_DOWNLOAD_AUDIO_FILE : 
				threadDonwoloadAudioMessage();
				break;
				
				// 녹음한 음성을 재생한다
			case THREAD_INIT_PLAYING : 
				runOnUiThread(initToPlay);
				break;
				// 녹음한 음성을 재생한다
			case THREAD_PLAYING_RECORD : 
				runOnUiThread(playRecording);
				break;
							
				// (서버 통신) 프로그레스 바를 출력 한다.
			case THREAD_PROGRESS_BAR_VISIBLE : 
					dialog.show();
				break;
				// (서버 통신) 프로그레스 바를 감춘다.
			case THREAD_PROGRESS_BAR_INVISIBLE : 
				dialog.hide();
				break;
				// (서버 통신) 전송 성공 토스트를 띄운다	
			case THREAD_TOAST_SEND_SUCCESS : 
				showToastAudioSendSuccess();		
				break;	
				// (서버 통신) 전송 실패 토스트를 띄운다
			case THREAD_TOAST_SEND_FAIL :
				showToastAudioSendFail();
				break;	
				
				// 음성 메시지 삭제 확인받는다  -> 확인 누르면 삭제 후 종료
			case CONFIRM_DELETE_RECEIVE_AUDIO_FILE :
				runOnUiThread(confirmDeleteAudioToDownload);		
				break;	
				
				// 받은 저장 음성 메시지를 서버에서 삭제 한다		
			case THREAD_DELETE_RECEIVE_AUDIO_FILE :
				threadDeleteAudioMessage();	
				break;	
				// 받은 저장 음성 메시지를 서버에서 삭제하고 종료한다
			case THREAD_DELETE_RECEIVE_AUDIO_FILE_AND_FINISH :
				threadDeleteAudioMessageAndFinish();	
				break;	
				// 음성 메시지 삭제 성공 토스트를 띄운다			showToastAudioDeleteToSuccess	showToastAudioDeleteToFail
			case THREAD_TOAST_DELETE_SUCCESS :
				showToastAudioDeleteToSuccess();
				break;	
				// 음성 메시지 삭제 실패 토스트를 띄운다
			case THREAD_TOAST_DELETE_FAIL :
				showToastAudioDeleteToFail();
				break;	
				
				// 받은 음성 메시지를 저장함에 저장할지 확인받는다
			case CONFIRM_SAVE_RECEIVE_AUDIO_FILE :
				runOnUiThread(confirmSaveAudioToStorage);		
				break;	
				
				// 받은 음성 메시지를 저장함에 저장한다
			case THREAD_SAVE_RECEIVE_AUDIO_FILE :
				saveReceiveMessageToDownload();
				break;	
				
				// 음성 메시지 저장 성공 토스트를 띄운다			
			case THREAD_TOAST_SAVE_SUCCESS :
				showToastAudioSaveToDownloadSuccess();		
				break;	
				// 음성 메시지 저장 실패 토스트를 띄운다
			case THREAD_TOAST_SAVE_FAIL :
				showToastAudioSaveToDownloadFail();
				break;	
				
				// 사용자 차단 확인
			case THREAD_CONFIRM_BLOCK_USER : 
				runOnUiThread(confirmBlockUser);		
				break;
				// 사용자 차단
			case THREAD_BLOCK_USER : 
				threadBlockUser();
				break;
				
				// 토스트 - 이미 차단된 사용자
			case THREAD_TOAST_ALREADY_BLOCK : 
				showToastAlreadyBlockUser();						
				break;
				// 토스트 - 차단 성공
			case THREAD_TOAST_BLOCK_SUCCESS : 
				showToastBlockUserSuccess();
				break;
				// 토스트 - 차단 실패
			case THREAD_TOAST_BLOCK_FAIL : 
				showToastBlockUserFail();
				break;
				
				// 메시지 읽음 업데이트
			case THREAD_UPDATE_READ_YN : 
				threadUpdateReadYn();				
				break;
				
				// 사용자 확인 창을 띄운다
			case ALERT_SHOW_MESSAGE:
				new AlertDialog.Builder(returnThis())
				.setTitle("SendMe")							
				.setMessage(b.getString("msg"))
				.setIcon(R.drawable.ic_launcher)		// 경고창.  
				.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						// 그냥 사용자 확인 용이기 때문에 추가 조작 없음.
					}})
					.setNegativeButton("", null).show();
				
			}
		}
	};
	
	
	/**
	 * 목록을 세팅해서 출력 한다.
	 */
	private Runnable showReceiveMessageList = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			Log.d(TAG,"showReceiveMessageList");
			if(receiveMessageList!=null){
				Log.d(TAG,"receiveMessageList.size():"+receiveMessageList.size());
				sendMeReceiveMessageForPlayerSlideMenuAdapter = new SendMeReceiveMessageForPlayerSlideMenuAdapter(returnThis(), SendMeAudioPlayForReceiveMessageActivity.this, receiveMessageList);
				listViewReceiveMessage.setAdapter(sendMeReceiveMessageForPlayerSlideMenuAdapter);
			}
		}
	};
	
	
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 재생 관련 기능들

	/**
	 * 음성 재생 준비
	 */
	private Runnable initToPlay = new Runnable() {
		@Override
		public void run() {
			if(filePath.length()>0){
				initMediaPlayer();
			}
		}
	};
	/**
	 * 녹음한 음성을 재생한다
	 */
	private Runnable playRecording = new Runnable() {
		@Override
		public void run() {
			if(filePath.length()>0){
				// 음성을 재생한다
				startPlay();
			}
		}
	};

	/*
	 * 진행바를 터치하여 미디어 플레이어를 컨트롤할수 있도록한다
	 */
	private void playSeekbarChange(View v){
		if(mPlayer.isPlaying()){
			SeekBar sb = (SeekBar)v;
			mPlayer.seekTo(sb.getProgress());
		}
	}

	/*
	 * 미디어 플레이어 초기화
	 */
	private void initMediaPlayer()
	{
		
		Log.d(TAG,"initMediaPlayer");
		
		// 미디어 플레이어 생성
		if (mPlayer == null)
			mPlayer = new MediaPlayer();
		else{
			mPlayer.reset();
		}
		mPlayer.setOnCompletionListener(this);
		String fullFilePath = filePath;
		try
		{
			mPlayer.setDataSource(fullFilePath);
			mPlayer.prepare();   
			int point = mPlayer.getDuration();
			playSeekbar.setMax(point);

			int maxMinPoint = point / 1000 / 60;
			int maxSecPoint = (point / 1000) % 60;
			String maxMinPointStr = "";
			String maxSecPointStr = "";

			if (maxMinPoint < 10)
				maxMinPointStr = "0" + maxMinPoint + ":";
			else
				maxMinPointStr = maxMinPoint + ":";

			if (maxSecPoint < 10)
				maxSecPointStr = "0" + maxSecPoint;
			else
				maxSecPointStr = String.valueOf(maxSecPoint);

			mTvPlayMaxPoint.setText(maxMinPointStr + maxSecPointStr);		// 시간 값?

			playSeekbar.setProgress(0);	// init
		}
		catch(Exception e)
		{
			Log.d("ProgressRecorder", "media player Prepare Error : " + e);
		}
	}

	// 재생 시작
	private void startPlay()
	{
		Log.d("ProgressRecorder", "startPlay().....");
		try
		{
			mPlayer.start();

			// SeekBar의 상태를 mProgressCheckStepMs 마다 체크      
			mProgressHandler2.sendEmptyMessageDelayed(0, mProgressCheckStepMs);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Toast.makeText(this, "error : " + e.getMessage(), 0).show();
		}
	}

	@Override
	public void onCompletion(MediaPlayer mp)
	{
		// 재생이 끝났으므로 진행바를 가장 끝으로 위치시킨다
		playSeekbar.setProgress(mPlayer.getDuration());
		// 재생이 종료되면 즉시 SeekBar 메세지 핸들러를 호출한다. 
		mProgressHandler2.sendEmptyMessageDelayed(0, 0);
	}

	
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 서버 통신

	
	/**
	 * 받은 음성 메시지를 가져온다			selectVoiceList
	 *  일반 리스트를 서버로 전송할때는 서버에서 RequestBody 로 받아서 json을 자동으로 object 변환시켜주므로
	 *    jsonArray 에 jsonObject 를 담을때 toString() 처리하여 담아서 보내야 하지만 
	 *  multipart로 파일을 전송하는 경우에는 서버에서 RequestParam 으로 받는데 이때에는 json을 자동으로 object 변환하지 않기 때문에
	 *   jsonArray 에 jsonObject 를 담을때 jsonObject 그대로 넣어야 서버에서 받을때 넣은 json 형태 그대로 꺼내어진다. 
	 */
	public void threadSelectVoiceList() {

		// 프로그레스 바를 출력 한다.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_VISIBLE));

		Thread thread = new Thread(new Runnable() {

			public void run() {
				Log.d(TAG,"threadSelectVoiceList");
				SendMeVoice sendMeVoice = new SendMeVoice();
				sendMeVoice.setReceiver(sender);			 
				sendMeVoice.setDeliveryYn("Y");				
				sendMeVoice.setActivateYn("Y");			

				SendMeAudioMessageRest sendMeAudioMessageRest = new SendMeAudioMessageRest();

				// 받은 메시지 목록		receiveMessageList
				ArrayList<SendMeVoice> resultReceiveMessageList = null;		
				
				resultReceiveMessageList = sendMeAudioMessageRest.selectVoiceList(sendMeVoice);		// 원본 (정상 동작)
				
				receiveMessageList = new ArrayList<SendMeVoice>();
				
//				SendMeCommon sendMeCommon = new SendMeCommon();
//				ArrayList<SendMeFriend> phoneBookAddress = sendMeCommon.selectPhoneBookAddress(returnThis());
				SendMeDBManagerInstallUser sendMeDBManagerInstallUser = new SendMeDBManagerInstallUser(returnThis());			
				ArrayList<SendMeFriend> phoneBookAddress = sendMeDBManagerInstallUser.selectInstallUserData();
				
				
				if(resultReceiveMessageList!=null){
					for(int i=0; i<resultReceiveMessageList.size(); i++){

						SendMeVoice tempSendMeVoice = resultReceiveMessageList.get(i);

						// 초기화
						resultReceiveMessageList.get(i).setSenderName("");
						
						// 전화번호부와 동기화하여 이름 세팅
						for(int j=0; j<phoneBookAddress.size(); j++){

							// 번호가 같으면 전화번호부의 닉네임(없으면 이름)으로 세팅
							if(tempSendMeVoice.getSender().equals(phoneBookAddress.get(j).getPhoneNumber())){
								if(phoneBookAddress.get(j).getNickName().length()>0){
									tempSendMeVoice.setSenderName(phoneBookAddress.get(j).getNickName());
								}else{
									tempSendMeVoice.setSenderName(phoneBookAddress.get(j).getName());
								}
//								tempSendMeVoice.setSenderName(phoneBookAddress.get(j).getName());
							}
						}
						receiveMessageList.add(tempSendMeVoice);
					}
				}
				
				// 화면에 출력
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SHOW_RECEIVE_MESSAGE_LIST));	
				
				// 프로그레스 바를 감춘다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_INVISIBLE));
				
				
			}
		});
		thread.start();
	}
	
	
	/**
	 * 음성 메시지를 다운받는다		selectFile
	 */
	public void threadDonwoloadAudioMessage() {

		// 프로그레스 바를 출력 한다.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_VISIBLE));
		
		Thread thread = new Thread(new Runnable() {

			public void run() {
				
				Log.d(TAG,"threadDonwoloadAudioMessage");
				
				SendMeFile sendMeFile = new SendMeFile();
				
				sendMeFile.setIdSendMeFile(receiveIdSendMeFile);					// 요청용 
				sendMeFile.setSendMeVoiceIdSendMeVoice(receiveIdSendMeVoice);		// 요청용
				sendMeFile.setSendMeVoiceSender(receiveSender);						// 요청용
				sendMeFile.setFileName(receiveFileName);				// 저장용

				SendMeAudioMessageRest sendMeAudioMessageRest = new SendMeAudioMessageRest();
				String result = sendMeAudioMessageRest.selectFile(sendMeFile);		
				filePath = result;
				
				if(result!=null && result.length()>0){
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_INIT_PLAYING));	// 재생 준비
				}
				
				// 프로그레스 바를 감춘다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_INVISIBLE));
			}
		});
		thread.start();
	}

	
	/**
	 * 서버에서 음성 메시지를 삭제한다
	 */
	public void threadDeleteAudioMessage() {

		// 프로그레스 바를 출력 한다.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_VISIBLE));
		
		Thread thread = new Thread(new Runnable() {

			public void run() {
				// TODO Auto-generated method stub
				
				Log.d(TAG,"threadDeleteAudioMessage");
				
				SendMeCommon sendMeCommon = new SendMeCommon();
				String nowTime = sendMeCommon.getCurrentDate();
				
				SendMeAudioMessageRest sendMeAudioMessageRest = new SendMeAudioMessageRest();
				
				SendMeVoice sendMeVoice = new SendMeVoice();
				sendMeVoice.setIdSendMeVoice(receiveIdSendMeVoice);
				sendMeVoice.setActivateYn("N");
				sendMeVoice.setModifyDate(nowTime);
				
				SendMeVoice result = sendMeAudioMessageRest.updateDeactivate(sendMeVoice);
					
				if(result.getResult().equals("SUCCESS")){		
					// "삭제 하였습니다."
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_DELETE_SUCCESS));				
					
					
					// 리스트 호출
					Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
					startActivity(intent);
					
					// 로컬에 저장된 거 지우고 나간다
					deleteFileAndFinishActivity();
				}else{
					// "삭제 실패했습니다."
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_DELETE_FAIL));
				}
				
				// 프로그레스 바를 감춘다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_INVISIBLE));
			}
		});
		thread.start();
	}
	
	/**
	 * 서버에서 음성 메시지를 삭제하고 종료한다
	 */
	public void threadDeleteAudioMessageAndFinish() {

		// 프로그레스 바를 출력 한다.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_VISIBLE));
		
		Thread thread = new Thread(new Runnable() {

			public void run() {
				// TODO Auto-generated method stub
				
				Log.d(TAG,"threadDeleteAudioMessage");
				
				SendMeCommon sendMeCommon = new SendMeCommon();
				String nowTime = sendMeCommon.getCurrentDate();
				
				SendMeAudioMessageRest sendMeAudioMessageRest = new SendMeAudioMessageRest();
				
				SendMeVoice sendMeVoice = new SendMeVoice();
				sendMeVoice.setIdSendMeVoice(receiveIdSendMeVoice);
				sendMeVoice.setActivateYn("N");
				sendMeVoice.setModifyDate(nowTime);
				
				SendMeVoice result = sendMeAudioMessageRest.updateDeactivate(sendMeVoice);
					
				if(result.getResult().equals("SUCCESS")){		
//					// "삭제 하였습니다."
//					mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_DELETE_SUCCESS));				
					
					// 리스트 호출
					Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
					startActivity(intent);
					
					// 로컬에 있는 것은 삭제하지 않고 종료한다
//					// 화면을 닫는다.
//					sendMeActivityManager.removeActivity(SendMeAudioPlayForReceiveMessageActivity.this);
//					finish();
					
					mediaPlayerReleaseAndFinishThisActivity();
				}else{
					// "삭제 실패했습니다."
					mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_DELETE_FAIL));
				}
				
				// 프로그레스 바를 감춘다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_INVISIBLE));
			}
		});
		thread.start();
		
	}
	
	/**
	 * 사용자를 차단한다		
	 *    먼저 중복 확인 호출하고 이후 사용자를 차단하는 메소드를 호출한다
	 */
	public void threadBlockUser() {
		
		// 프로그레스 바를 출력 한다.
		mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_VISIBLE));
		
		Thread thread = new Thread(new Runnable() {
			
			public void run() {
				
				SendMeCommon sendMeCommon = new SendMeCommon();
				String nowTime = sendMeCommon.getCurrentDate();
				
				SendMeBlock sendMeBlock = new SendMeBlock();
				
				// 차단 대상 전화번호 : 보낸 사람
				String blockUserNumber = receiveSender;
				sendMeBlock.setPhoneNumber(blockUserNumber);				// 너		 
				sendMeBlock.setActivateYn("Y");
				sendMeBlock.setSendMeMemberPhoneNumber(sender);			// 나
				
				SendMeBlockRest sendMeBlockRest = new SendMeBlockRest();
				SendMeBlock result = sendMeBlockRest.selectDuplicate(sendMeBlock);
				
				// 최초 차단
				if(result.getTotalCount().equals("0")){		

					sendMeBlock = new SendMeBlock();
					
					sendMeBlock.setPhoneNumber(blockUserNumber);
					sendMeBlock.setActivateYn("Y");
					sendMeBlock.setModifyDate(nowTime);
					sendMeBlock.setRegisterDate(nowTime);
					sendMeBlock.setSendMeMemberPhoneNumber(sender);
					
					result = sendMeBlockRest.registerBlock(sendMeBlock);
					
					if(result.getResult().equals("SUCCESS")){		
						// "차단하였습니다."
						mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_BLOCK_SUCCESS));
						
//						// 1. (삭제 하는 경우)차단 성공하면 파일은 삭제한다			// ### 
//						mHandler.sendMessage(mHandler.obtainMessage(THREAD_DELETE_RECEIVE_AUDIO_FILE));
						
						// 2. (삭제 안하는 경우)리스트 호출
						Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
						startActivity(intent);
						// 로컬에 저장된 거 지우고 나간다
						deleteFileAndFinishActivity();
						
						
					}else{
						// "차단 실패했습니다."
						mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_BLOCK_FAIL));
					}
				// 전에 차단한적 있는 경우	
				}else{
					
					if(result.getActivateYn().equals("Y")){	
						// "이미 차단 하셨어요"		
						mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_ALREADY_BLOCK));
					}else{
						// updateBlock 을 사용해서 차단한다.
						sendMeBlock = new SendMeBlock();
						
						sendMeBlock.setPhoneNumber(blockUserNumber);
						sendMeBlock.setActivateYn("Y");			// 차단. 해제시에는 N으로 업뎃
						sendMeBlock.setModifyDate(nowTime);
						sendMeBlock.setSendMeMemberPhoneNumber(sender);
						
						result = sendMeBlockRest.updateBlock(sendMeBlock);
						
						if(result.getResult().equals("SUCCESS")){		
							// "차단하였습니다."
							mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_BLOCK_SUCCESS));
							
							
							
//							// 1. (삭제 하는 경우)차단 성공하면 파일은 삭제한다			// ### 
//							mHandler.sendMessage(mHandler.obtainMessage(THREAD_DELETE_RECEIVE_AUDIO_FILE));
							
							// 2. (삭제 안하는 경우)리스트 호출
							Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
							startActivity(intent);
							// 로컬에 저장된 거 지우고 나간다
							deleteFileAndFinishActivity();
							
							
							
						}else{
							// "차단 실패했습니다."
							mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_BLOCK_FAIL));
						}
					}
				}
				
				// 프로그레스 바를 감춘다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PROGRESS_BAR_INVISIBLE));
			}
		});
		thread.start();
	}
	
	
	/**
	 * 메시지 읽음 업데이트		
	 */
	public void threadUpdateReadYn() {
		
		Thread thread = new Thread(new Runnable() {
			
			public void run() {
				SendMeCommon sendMeCommon = new SendMeCommon();
				String nowTime = sendMeCommon.getCurrentDate();
				
				SendMeRecognitionRest sendMeRecognitionRest = new SendMeRecognitionRest();
				
				SendMeRecognition sendMeRecognition = new SendMeRecognition();		// receiveIdSendMeVoice		receiveSender		sender
				sendMeRecognition.setPhoneNumber(sender);
				sendMeRecognition.setReadYn("Y");
				sendMeRecognition.setActivateYn("Y");
				sendMeRecognition.setModifyDate(nowTime);
				sendMeRecognition.setSendMeVoiceIdSendMeVoice(receiveIdSendMeVoice);
				sendMeRecognition.setSendMeVoiceSender(receiveSender);
				
				Log.d(TAG,"setPhoneNumber:"+sender);
				Log.d(TAG,"setModifyDate:"+nowTime);
				Log.d(TAG,"setSendMeVoiceIdSendMeVoice:"+receiveIdSendMeVoice);
				Log.d(TAG,"setSendMeVoiceSender:"+receiveSender);
				
				SendMeRecognition result = sendMeRecognitionRest.updateReadYn(sendMeRecognition);
					
				if(result.getResult().equals("SUCCESS")){		
					Log.d(TAG,"updateReadYn SUCCESS");
					
					// pref 에 읽음 개수 업데이트 해준다.
					// 안읽은 메시지 개수 감소
					int unReadCount = sendMeCommon.badgeCountPrefLoad(returnThis());
					unReadCount = unReadCount-1;
					Log.d(TAG,"unReadCount::"+unReadCount);
					sendMeCommon.badgeCountPrefSave(returnThis(), unReadCount);
					// 뱃지 업데이트
					sendMeCommon.badgeCountAutoSet(returnThis());
				}else{
					Log.d(TAG,"updateReadYn FAIL");
				}
			}
		});
		thread.start();
	}
	
	/**
	 * 로그를 남긴다	 
	 */
	public void threadRegisterLog() {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				
				SendMeCommon sendMeCommon = new SendMeCommon();
				String nowTime = sendMeCommon.getCurrentDate();
				
				SendMeLog sendMeLog = new SendMeLog();
				sendMeLog.setPhoneNumber(sender);
				sendMeLog.setViewName(TAG);
				sendMeLog.setRegisterDate(nowTime);
				
				SendMeLogRest sendMeLogRest = new SendMeLogRest();
				
				sendMeLogRest.registerLog(sendMeLog);
			}
		});
		thread.start();
	}
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Bundle extraBundle;
		if( requestCode == PASSWORD_ACTIVITY_CODE ) {
			if(resultCode == Activity.RESULT_OK) {		// 정상 반환시.
				
				Log.d(TAG,"RESULT_OK");
				extraBundle = data.getExtras();		// 번들을 반환했으니까 번들을 불러오면 세팅된 값을 가지고 있음.

				int actionCode = extraBundle.getInt("actionCode");	
				String passwordActivityResult = extraBundle.getString("passwordActivityResult");	
				Log.d(TAG,"passwordActivityResult:"+passwordActivityResult);
				
				if(passwordActivityResult.equals("SUCCESS")) {
						// nothing to do
						
						// 메시지 읽음 업데이트
						if(!receiveReadYn.equals("Y")){
							mHandler.sendMessage(mHandler.obtainMessage(THREAD_UPDATE_READ_YN));		
						}
						
						// 음성 메시지 파일 다운로드 
						mHandler.sendMessage(mHandler.obtainMessage(THREAD_DOWNLOAD_AUDIO_FILE));
				}
				
			} else if(resultCode == Activity.RESULT_CANCELED) {
				Log.d(TAG,"PASSWORD_ACTIVITY_CODE RESULT_CANCELED");
				// 리스트로
				Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
				startActivity(intent);

				mediaPlayerReleaseAndFinishThisActivity();
			}
		}else if(requestCode == RECORDING_SCREEN_CALL){
			if(resultCode == Activity.RESULT_OK){		// 정상 반환시.
				Log.d(TAG,"resultCode == Activity.RESULT_OK");
				Log.d(TAG,"RESULT_OK");
//				extraBundle = data.getExtras();		// 번들을 반환했으니까 번들을 불러오면 세팅된 값을 가지고 있음.

//				String key1 = extraBundle.getString("key1");	
//				Log.d(TAG,"key1:"+key1);
				
				// 리스트 호출
				Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
				startActivity(intent);
				
				// 화면을 닫는다.
				deleteFileAndFinishActivity();
				
			}else if(resultCode == Activity.RESULT_CANCELED){
				Log.d(TAG,"RESULT_CANCELED");
			}
			else if(resultCode == RESULT_MAIN_MENU_CALLED){
				Log.d(TAG,"RESULT_MAIN_MENU_CALLED");
				
				// 화면을 닫는다.
				deleteFileAndFinishActivity();
			}
		}

	}
	
	
	
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 슬라이드 메뉴 관련 메소드 
	
	/**
	 * 슬라이드 메뉴 기능 초기화
	 */
	public void initSlideFunction(){

		// init left menu width
		metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		// 화면의 1/3 정도는 밀어줘야 나오도록 하기.
		scrollingWidthBandwith = (int) ((metrics.widthPixels) * 0.3);

		m_viewFlipper = (ViewFlipper) app.findViewById(R.id.viewFlipper1);  
		m_viewFlipper.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {  
					m_nPreTouchPosX = (int) event.getX();  
				}  

				if (event.getAction() == MotionEvent.ACTION_UP) {  
					int nTouchPosX = (int) event.getX();  

					if (nTouchPosX < m_nPreTouchPosX) {  
						//						Log.d(TAG,"MoveNextView");
					} else if (nTouchPosX - m_nPreTouchPosX > scrollingWidthBandwith) {  // (nTouchPosX > m_nPreTouchPosX)  --> (nTouchPosX - m_nPreTouchPosX >200)  --> scrollingWidthBandwith
						//						Log.d(TAG,"MovewPreviousView");
						slideMenuOpenClose();		
					}  
					m_nPreTouchPosX = nTouchPosX;  
				}  
				return true;  
			}
		});  

		final View[] children = new View[] { menu, app };		// ### 

		int scrollToViewIdx = 1;
		scrollView.initViews(children, scrollToViewIdx, new SendMeSlideSizeCallbackForMenu(this));

	}

	/**
	 * 메소드 호출로 슬라이드 메뉴 컨트롤
	 */
	public void slideMenuOpenClose(){

		int menuWidth = menu.getMeasuredWidth();

		// Ensure menu is visible
		menu.setVisibility(View.VISIBLE);

		if (!isLeftExpanded) {
			
			// Scroll to 0 to reveal menu
			int left = 0;
			scrollView.smoothScrollTo(left, 0);
			m_viewFlipper.setEnabled(false);

			// 메인의 요소들은 디스걸고
			// disable all of main view
			FrameLayout viewGroup = (FrameLayout) app.findViewById(R.id.ll_fragment)
					.getParent();
			enableDisableViewGroup(viewGroup, false);

			// 메인쪽을 터치하면 empty 가 받아서 토글 -> 왼쪽창을 닫는다.
			// enable empty view
			((LinearLayout) app.findViewById(R.id.ll_empty)).setVisibility(View.VISIBLE);

			app.findViewById(R.id.ll_empty).setEnabled(true);
			app.findViewById(R.id.ll_empty).setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View arg0, MotionEvent arg1) {
					slideMenuOpenClose();
					return true;
				}
			});
			
//			 데이터가 세팅되지 않았다면 데이터를 세팅하도록 한다.
			if(receiveMessageList==null || receiveMessageList.size()<1){
				Log.d(TAG,"THREAD_SELECT_RECEIVE_MESSAGE_LIST");
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SELECT_RECEIVE_MESSAGE_LIST));				
			}

		} else {
			// Scroll to menuWidth so menu isn't on screen.
			int left = menuWidth;
			scrollView.smoothScrollTo(left, 0);
			m_viewFlipper.setEnabled(true);

			// 메인쪽의 모든 요소들을 사용가능하게 하고
			// enable all of main view
			FrameLayout viewGroup = (FrameLayout) app.findViewById(R.id.ll_fragment).getParent();
			enableDisableViewGroup(viewGroup, true);

			// 엠티뷰(왼쪽창을 돌려보낼때 사용) 는 비활성한다
			// disable empty view
			((LinearLayout) app.findViewById(R.id.ll_empty)).setVisibility(View.GONE);
			app.findViewById(R.id.ll_empty).setEnabled(false);

		}
		isLeftExpanded = !isLeftExpanded;
	}


	/**
	 * 뷰의 동작을 제어한다. 하위 모든 뷰들이 enable 값으로 설정된다.
	 * 
	 * @param viewGroup
	 * @param enabled
	 */
	public static void enableDisableViewGroup(ViewGroup viewGroup,
			boolean enabled) {
		int childCount = viewGroup.getChildCount();
		for (int i = 0; i < childCount; i++) {
			View view = viewGroup.getChildAt(i);
			view.setEnabled(enabled);
			if (view instanceof ViewGroup) {
				enableDisableViewGroup((ViewGroup) view, enabled);
			}
		}
	}
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 슬라이드 메뉴 - 메시지 리스트에서 버튼 클릭시 호출
	
	/**
	 * showResultDialog
	 * 확인 창을 띄운다
	 *
	 * @param msg
	 * @param 
	 * @return 
	 */
	public void showAlertMessage(final String msg) {
		runOnUiThread(new Runnable() {		 
			@Override
			public void run(){
				Message message = mHandler.obtainMessage(ALERT_SHOW_MESSAGE);				
				Bundle b = new Bundle();
				b.putString("msg", msg);			// 화면에 보여줄 메시지
				message.setData(b);
				mHandler.sendMessage(message);
			}
		});
	}
	
	// 재생 버튼 클릭시 파라미터를 세팅하여 받은 파일 전용 재생 액티비티를 실행시킨다 + 자신은 종료
	public void playAudioMessage(SendMeVoice sendMeVoice){
		
		SendMeCommon sendMeCommon = new SendMeCommon();
		
		Intent intent = new Intent(SendMeAudioPlayForReceiveMessageActivity.this, SendMeAudioPlayForReceiveMessageActivity.class);
		String senderName = sendMeCommon.selectFriendNameByPhoneNumber(returnThis(), sendMeVoice.getSender());
		intent.putExtra("idSendMeVoice", sendMeVoice.getIdSendMeVoice());
		intent.putExtra("sender", sendMeVoice.getSender());
		intent.putExtra("senderName", senderName);
		intent.putExtra("fileName", sendMeVoice.getFileName());
		intent.putExtra("idSendMeFile", sendMeVoice.getIdSendMeFile());
		intent.putExtra("readYn", sendMeVoice.getReadYn());
		startActivity(intent);
		
		deleteFileAndFinishActivity();
	}
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// 컨텍스트 반환
	public Context returnThis() {
		return this;
	}
	
	/**
	 * SharedPreference 정보를 확인 한다.
	 */
	public void confirmNotification() {
		SharedPreferences mSharedPreference = getSharedPreferences(SendMeConstant.SENDME_PREFERENCE, Activity.MODE_PRIVATE);
		sender = mSharedPreference.getString("phone_number", "");
		FUNCTION_MODE = mSharedPreference.getString("function_mode", "");
		Log.i(TAG, "sender : " + sender);
	}

	
	/**
	 * sqlite 에 받은 메시지 정보를 저장한다. (보관함에 저장)
	 *  저장 이후 액티비티를 종료한다. (파일은 지우지 않는다)
	 */
	public void saveReceiveMessageToDownload(){
		
		// 현시각
		SendMeCommon sendMeCommon = new SendMeCommon();
		String nowTime = sendMeCommon.getCurrentDate();
		
		SendMeVoice sendMeVoice = new SendMeVoice();
		
		// 메시지를 보낸 사람 정보
		sendMeVoice.setSender(receiveSender);
		sendMeVoice.setSenderName(receiveSenderName);
		// 받는 사람 정보 (나)
		sendMeVoice.setReceiver(sender);

		// 현 시각
		sendMeVoice.setRegisterDate(nowTime);
		sendMeVoice.setModifyDate(nowTime);

		// 파일 정보
		sendMeVoice.setFileName(receiveFileName);
		sendMeVoice.setFilePath(filePath);

		// sqlite 에 저장
		SendMeDBManagerAudioRecord sendMeDBManagerAudioRecord = new SendMeDBManagerAudioRecord(this);
		if(sendMeDBManagerAudioRecord.insertDownloadAudioData(sendMeVoice)) {
			
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_SAVE_SUCCESS));		
			
			// 저장 성공하면 서버에서는 삭제하고 종료한다.
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_DELETE_RECEIVE_AUDIO_FILE_AND_FINISH));
			
		} else {
			mHandler.sendMessage(mHandler.obtainMessage(THREAD_TOAST_SAVE_FAIL));		// 다운로드 메시지에 저장 실패..
		}
	}
	
	
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 액티비티 종료 관련 기능들

	
	/**
	 * 뒤로 가기 버튼을 정의 한다.
	 * 화면을 종료 한다.
	 */
	@Override
	public void onBackPressed() {
		super.onBackPressed();
		
		// 리스트로
		Intent intent = new Intent(returnThis(), SendMeReceiveVoiceListActivity.class);
		startActivity(intent);
		
		deleteFileAndFinishActivity();
	}

	/**
	 * 액티비티를 종료한다
	 *  디바이스의 뒤로가기 버튼으로 인한 종료 / 화면에서의 버튼 조작에 의한 액션 처리 이후 닫을때 호출된다
	 */
	public void deleteFileAndFinishActivity(){
		// 파일이 있다면 지운다.
		checkAndDeleteFile();
		
		// 화면을 닫는다.
		mediaPlayerReleaseAndFinishThisActivity();
	}

	/**
	 * 임시 파일이 있는지 체크하고 있다면 지운다.
	 */
	public void checkAndDeleteFile(){
		
		if(mPlayer!=null){
			mPlayer.reset();
			//			mPlayer.release();	
			mPlayer = null;
		}
		
		String fileChk = filePath;
		File file = new File(fileChk);
		if(file.exists()){
			file.delete();
			Log.d(TAG,"file delete success");
		}
	}

	/**
	 * 종료. 미디어 플레이어 릴리즈
	 */
	public void mediaPlayerReleaseAndFinishThisActivity(){
		// 초기화
		if(mPlayer!=null){
			mPlayer.reset();
//			mPlayer.release();
			mPlayer = null;
		}
		// 화면을 닫는다.
		sendMeActivityManager.removeActivity(SendMeAudioPlayForReceiveMessageActivity.this);
		finish();
	}
	
	@Override
	public void onResume(){
		super.onResume();
		dialog = ProgressDialog.show(SendMeAudioPlayForReceiveMessageActivity.this, "", "Wait..", true);	// 제목, 내용
		dialog.hide();
	}
	@Override
	public void onStop(){
		super.onStop();
		dialog.dismiss();
	}
	
}
